<?php
/**
 * Created by PhpStorm.
 * User: xiong <1099446868@qq.com>
 * DateTime: 2018/12/16
 * TIME: 0:09
 */

namespace app\index\model;

use think\facade\Cache;
use think\Db;
use think\facade\Config;
use think\facade\Cookie;

class Book extends BaseModel {

    public static function getBookById($id, $table) {

        if (Cache::has('book_' . $id)) {
            return Cache::get('book_' . $id);
        } else {
            $arr = Db::name('bookname')
                ->where('id', $id)
                ->find();
            $category = self::category($arr['source'], $arr['category']);
            $arr = array_merge($arr, $category);
            $arr['start'] = self::getStart5Chapter($id, $table);
            $arr['catalogCount'] = self::getCatalogCount($id, $table);
            Cache::set('book_' . $id, $arr, config('cache_time'));
            return $arr;
        }
    }

    //获取第一章(暂不需要 没调用)
    public static function getStartChapter($id, $table) {
        return Db::name($table)->field('id as sid,title as stitle')->where('bid', $id)->find();
    }

    //获取最后一章
    public static function getEndChapter($id, $table) {
        return Db::name($table)->field('id as eid,title as etitle')->where('bid', $id)->order('id desc')->find();
    }

    //获取前五章
    public static function getStart5Chapter($id, $table) {

        return Db::name($table)->field('id,title')->where('bid', $id)->limit(5)->select();
    }

    //获取后五章
    public static function getEnd5Chapter($id, $table) {
        return Db::name($table)->field('id,title')->where('bid', $id)->order('id desc')->limit(5)->select();
    }

    /**
     * @param $source  book来源
     * @param $cid     category值
     * @return mixed
     */
    public static function category($source, $cid) {
        $category = Config::get('category');
        $arr = [];
        $arr['category'] = $category[$source][$cid]['name'];
        $arr['category_url'] = $category[$source][$cid]['url'];
        return $arr;
    }

    //获取单个章节 //决定不将内容缓存，太大了
    public static function getCatalogById($id, $table) {
//        if (Cache::has('catalog_' . $id)) {
//            return Cache::get('catalog_' . $id);
//        } else {
            $catalog = Db::name($table)
                ->where('id', $id)
//                ->cache('catalog_' . $id, config('catalog_time'))
                ->find();

            return $catalog;
//        }
    }

    //获取全部章节
    public static function getCatalogsByBid($id, $table) {
        if (Cache::has('catalogs_' . $id)) {
            return Cache::get('catalogs_' . $id);
        } else {

            $catalog = Db::name($table)
                ->field('id,bid,bookname,title,url')
                ->where('bid', $id)
                ->cache('catalogs_' . $id, config('catalogs_time'))
                ->select();

            return $catalog;
        }
    }

    public static function getCatalogCount($id, $table) {
        return Db::name($table)->where('bid', $id)->count();
    }

    public static function content($bid, $id, $table) {
        if (Cache::has('book_' . $bid)) {
            $book = Cache::get('book_' . $bid);
            $source = $book['source'];
        } else {
            $arr = Db::name('bookname')
                ->where('id', $bid)
                ->find();
            $category = self::category($arr['source'], $arr['category']);
            $book = array_merge($arr, $category);
            Cache::set('book_' . $bid, $book, config('cache_time'));
            $source = $book['source'];
        }


        $catalogs = self::getCatalogsByBid($bid, $table);  //所有目录
        $catalog = self::getCatalogById($id, $table);  //本章记录

        //上一章和下一章
        foreach ($catalogs as $k => $v) {
            if ($catalog['id'] == $v['id']) {
                $current = $k;
            }
        }
        $prev = [];
        $next = [];
        if ($current >= 1) {
            $prev = $current - 1;
            $prev = $catalogs[$prev];
            $prev['bid'] = $bid;
        }
        $count = self::getCatalogCount($bid, $table);
        if ($current + 1 < $count) {
            $next = $current + 1;
            $next = $catalogs[$next];
            $next['bid'] = $bid;
        }

        if ($catalog['status'] == 1) {
            //说明数据库中有值,且已经缓存了，将其读出
            $content = gzuncompress($catalog['content']);
        } else {

            //抓取内容
            if ($source == 'zwdu') {
                $url = 'https://www.' . $source . '.com' . $catalog['url'];
                $html = curl_get($url);
                $xpath = config('xpath');
                $select = $xpath[$source]['content'];
                $content = getContent($html, $select);
            }
            if (!empty($content)) {
                $content = ltrim($content, '<div id="content">');
                $content = rtrim($content, '</div>');
                Db::name($table)->where('id', $id)->update(['content' => gzcompress($content), 'status' => 1]);
            } else {
                $content = '获取本章失败，请刷新重试！';
            }

        }


        $book['content'] = $content;
        $book['wordnum'] = mb_strlen($content);
        $book['title'] = $catalog['title'];
        $book['prev'] = $prev;
        $book['next'] = $next;

        return $book;
    }

    /**
     * @param $searchname
     * @return array|false|mixed|null|\PDOStatement|string|\think\Model
     *  先从自身数据库中搜索，搜不到再从远程搜索，本地搜到后显示小说详情页面，远程搜到后显示检索页面，检索页面根据用户
     *  的选择爬取
     */
    public static function getBookByBookName($searchname) {

        $source = self::getSource();
        $book = self::isBookInMySelf($searchname, $source);
        if (!is_null($book)) {
            return $book;
        }else{
            return false;
        }

        //本库中没找到  在外网找  以下未完成
        $xpath = config('xpath');
        //url中出现中文需要编码
        $url = $xpath[$source]['search']['url'] . urlencode($searchname);
        $search_html = curl_get($url);
        $fields = $xpath[$source]['search']['fields'];
        $books = getConFromHtml($search_html, $fields);
        $return['books'] = self::updateFields($books, $source);
        $return['searchname'] = $searchname;
        //获取末页
        $lastpage = $xpath[$source]['search']['field']['lastpage'];
        $lastpage = getContent($search_html, $lastpage);
        if (!empty($lastpage)) {
            $lastpage = explode('page=', $lastpage);
            $lastpage = explode(' ', $lastpage[1]);
            $lastpage = (int)$lastpage[0];
            $return['lastpage'] = $lastpage;
        }
        //dump($return);exit;
        return $return;
    }

    public static function saveBook($books, $source) {
        $category = config('category_id');
        //dump($books);exit;
        foreach ($books as $k => $v) {
            $exists = Db::name('bookname')->where('bookname', $v['bookname'])->find();
            if (is_null($exists)) {
                $data = [
                    'category'   => $category[$v['category']],
                    'bookname'   => $v['bookname'],
                    'author'     => $v['author'],
                    'source'     => $v['source'],
                    'url'        => $v['link'],
                    'bookstatus' => 1,
                    'updatetime' => $v['updatetime'] . ' 23:00:00',
                    'desc'       => addslashes($v['desc'])
                ];
                $insertId = Db::name('bookname')->insert($data);
            }
        }
    }

    public static function isBookInMySelf($bookname, $source) {
        $book = [];
        if (Cache::has('bookname_' . $bookname)) {
            $book = Cache::get('bookname_' . $bookname);
        } else {
            $book = Db::name('bookname')
                ->where('bookname|author', $bookname)
                ->find();

            if (!is_null($book)) {

                $category = self::category($source, $book['category']);
                $table = switchTableById2($book['id']);
                $book = array_merge($book, $category);
                $book['start'] = self::getStart5Chapter($book['id'], $table);
                $book['catalogCount'] = self::getCatalogCount($book['id'], $table);
                Cache::set('bookname_' . $bookname, $book, config('cache_time'));
            }

        }
        return $book;
    }

    public static function updateFields($return, $source) {
        if ($source == 'zwdu') {
            foreach ($return as $k => $v) {
                $link = explode('"', $v['link']);
                $return[$k]['bookname'] = $link[5];
                $link = explode('/', $link[3]);
                $link = '/' . $link[3] . '/' . $link[4] . '/';
                $return[$k]['link'] = $link;

                $return[$k]['author'] = trim($v['author']);
                $return[$k]['source'] = 1;
            }
        }

        return $return;
    }

    public static function SearchToDetails($param) {

        $source = $param['source'];  //int
        $source_host = config('source_host');
        $source_host = $source_host[$source];
        $url = $source_host . $param['link'];
        //dump($url);
        $html = curl_get($url);
        //获取章节信息并入库
        $xpath = config('xpath');
        $source = config('source')[$source];  //string
        $bookstatus = $xpath[$source]['searchtodetails']['field']['bookstatus']['select'];
        $bookstatus = getContent($html, $bookstatus, true);
        if ($bookstatus == '') { //作为能否成功取到数据数据的依据
            return '暂无数据';
        }
        if (mb_strpos($bookstatus, '连载') === false) {
            $bookstatus = 1;
        } else {
            $bookstatus = 2;//已完结
        }
        $param['bookstatus'] = $bookstatus;
        $updatetime = $xpath[$source]['searchtodetails']['field']['updatetime']['select'];
        $updatetime = getContent($html, $updatetime, true);
        $updatetime = substr(trim($updatetime), 15);
        $param['updatetime'] = $updatetime;
        //先保存详情
        $exists = Db::name('zwdu')->where('bookname', $param['bookname'])->find();
        if (is_null($exists)) {
            $category = config('category_id');
            $param['category'] = $category[$param['category']];
            $param['url'] = $url;
            $param['desc'] = addslashes($param['desc']);
            $param['source'] = $source;
            $id = Db::name($source)->strict(false)->insertGetId($param);
            $id = (int)$id;
            if ($id > 0 && $id !== 1) {
                //dump($id);exit;
                $fields = $xpath[$source]['searchtodetails']['fields'];
                self::getConAndSave($html, $fields, $id, $param['bookname']);
                //return self::getBookById($id);
            }
        }
    }

    //爬取并保存章节  2191124
    public static function getConAndSave(string $html, array $fields = [], $id, $bookname) {
        $return = [];
        $document = new \DOMDocument();
        @$document->loadHTML($html);
        $xpath = new \DOMXPath($document);
        if (!empty($fields) && is_array($fields)) {
            $elements_s = $xpath->query($fields['title']['select']);
            //dump($elements_s);
            if ($elements_s->length != 0) {
                $table = switchTableById($id);
                $sql = "insert into '" . $table . "'(bid,bookname,`title`,url) values";
                for ($i = 0; $i < $elements_s->length; $i++) {
                    $title = $elements_s[$i]->nodeValue;
                    $title = addslashes($title);
                    $url = $elements_s[$i]->attributes[0]->nodeValue;
                    $sql .= "($id,'" . $bookname . "','" . $title . "','" . $url . "'),";
                }
                $sql = rtrim($sql, ',');

                //dump($table);exit;
                echo $sql;
                exit;
                Db::execute($sql);
            }

        }

        //return $return;
    }

    public static function rank($rid, $page) {
        //Cache::rm('RankingList' . $rid . '_' . $page);
        if (Cache::has('RankingList' . $rid . '_' . $page)) {
            $rankingList = Cache::get('RankingList' . $rid . '_' . $page);
        } else {
            $rankingList = self::RankingList($rid, $page);
            Cache::set('RankingList'.$rid.'_'.$page, $rankingList, config('RankingList_time'));
        }
        return $rankingList;
    }

    public static function RankingList($rid, $page) {
        $rank = Cache::get('rank');
        array_unshift($rank, []);
        $s = [
            'bookname'       => '//div[@class="rank_d_b_name"]/a',
            'author'         => '//div[@class="rank_d_b_cate"]/a[1]',
            'desc'           => '//div[@class="rank_d_b_info"]',
            'category'       => '//div[@class="rank_d_b_cate"]/a[2]',
            'bookstatus'     => '//div[@class="rank_d_b_cate"]/a[3]',
            'lastupdate'     => '//div[@class="rank_d_b_last"]/@title',
            'lastupdatetime' => '//span[@class="rank_d_b_time"]',
            'img'=>'//div[@class="rank_d_book_img fl"]/a/img/@src',
        ];
        $r = [];

        $url = $rank[$rid]['url'] . '&p=' . $page;
        $html = curl_get($url);
        $con = getContent($html, $rank[$rid]['select']);
        foreach ($con as $k => $c) {
            if ($k <= 19) {
                $r[$k]['bookname'] = getContent('<?xml encoding="UTF-8">' . $c, $s['bookname'], true);
                $r[$k]['author'] = getContent('<?xml encoding="UTF-8">' . $c, $s['author'], true);
                $r[$k]['desc'] = getContent('<?xml encoding="UTF-8">' . $c, $s['desc'], true);
                $r[$k]['category'] = getContent('<?xml encoding="UTF-8">' . $c, $s['category'], true);
                $r[$k]['bookstatus'] = getContent('<?xml encoding="UTF-8">' . $c, $s['bookstatus'], true);
                $r[$k]['lastupdate'] = getContent('<?xml encoding="UTF-8">' . $c, $s['lastupdate'], true);
                $r[$k]['lastupdatetime'] = getContent('<?xml encoding="UTF-8">' . $c, $s['lastupdatetime'], true);
                $img = ltrim(getContent('<?xml encoding="UTF-8">' . $c, $s['img']), ' src="');
                $r[$k]['img'] = rtrim($img, '"');
            }
        }
        return $r;
    }
}